
/**
 * 存储购物车数据
 */
//
/** 线上购物车API
 * mergeLocalCart 导入合并本地数据api
 * findCartList  导入获取登录后最新购物车数据的api
 * insertCart  导入 加入购物车api
 * deleteCart  删除购物车api
 * updateCart  修改商品单选api
 * checkAllCart  全选反选
 */
import { mergeLocalCart, findCartList, insertCart, deleteCart, updateCart, checkAllCart } from '@/api/cart'

export default {
  namespaced: true,
  state: () => ({
    // 购物车列表
    list: []
  }),

  getters: {
    // 购物车有效商品列表
    validList: state => {
      return state.list.filter(good => good.isEffective)
    },
    // 有效的总数量
    totalCounts (state, getters) {
      return getters.validList.reduce((acc, good) => acc + good.count, 0)
    },
    // 有效总价
    totalPrices (state, getters) {
      return getters.validList.reduce((acc, good) => acc + good.count * good.nowPrice, 0)
    },
    // 选中的列表
    seledList (state, getters) {
      // 选中的商品有效
      return getters.validList.filter(good => good.selected === true)
    },
    // 选中的列表总价
    seledListTotalPrices (state, getters) {
      return getters.seledList.reduce((acc, good) => acc + good.count * good.nowPrice, 0)
    },
    // 是否全部选择
    isAll (state, getters) {
      // validList =[],  every执行判断后  返回是 true   -->  这是底层逻辑,不对的
      // every 方法, 全部都选择才是true
      if (getters.validList.length) {
        return getters.validList.every(good => good.selected)
      }
      // 没有商品就默认不选
      return false
    }
  },

  mutations: {

    /** 存储 最新后台返回的购物车列表数据
     * @param {*} state  定义的数据
     * @param {*} list   返回的新购物车列表
     */
    setCartList (state, list) {
      state.list = list
    },
    // 加入购物车
    /**
     *
     * @param {*} state
     * @param {*} good 当前添加的商品
     */
    addCart (state, good) {
      /**
       * 加入购物车=》直接push？
       * 判断当前规格（SKU）的商品之前是否有添加过=》1. 添加过=》加数量 2. 没添加过=》新增
       */
      // isHaveIndex 返回存在商品在list的位置=》isHaveIndex>-1
      const isHaveIndex = state.list.findIndex((item) => item.skuId === good.skuId)
      if (isHaveIndex > -1) {
        // 加数量
        state.list[isHaveIndex].count += good.count
      } else {
        state.list.unshift(good)
      }
    },

    // 删除购物车商品
    delCart (state, good) {
      /**
       * 1. 找到被删除商品的索引
       * 2. 调用splice删除1个
       */
      const index = state.list.findIndex(item => item.skuId === good.skuId)
      state.list.splice(index, 1)
    },

    // 商品的单选
    singleCheck (state, { good, isCheck }) {
      /**
       * 1. 获取要修改的商品
       * 2. 使用这个商品修改选中状态
       */
      const currGood = state.list.find(item => item.skuId === good.skuId)
      currGood.selected = isCheck
    },

    // 商品的全选
    /**
     *
     * @param {*} state  商品数据
     * @param {*} selected  形参, 是否被选中的状态
     */
    selAllGoods (state, selected) {
      // 根据全选框的状态 selected ==> 修改list 所有商品的选择或者未选择
      // 循环遍历,list数组,并且把全选框的状态赋值
      state.list.forEach(good => {
        good.selected = selected
      })
    },

    // 商品修改数量
    changeCount (state, { newCount, good }) {
      /**
           * 1. 获取要修改的商品
           * 2. 使用这个商品修改最新数量
           */
      const currGood = state.list.find(item => item.skuId === good.skuId)
      currGood.count = newCount
    }
  },

  actions: {
    /**   定义获取当前登录人最新的购物车列表数据
     *
     * @param {*} param0
     */
    async getLoginCartAction ({ commit }) {
      // 调用 登录后最新购物车列表api,并解构出result
      const { result } = await findCartList()
      // 调用 mutations 中的 setCartList 方法, 并传值result
      commit('setCartList', result)
    },

    // 合并之前本地存储的购物车数据到当前登录人名下
    async mergeCartAction ({ state, dispatch }) {
      // 1-处理后台合并需要的购物车数据 -->  [{skuId,selected,count}]
      if (state.list.length) {
        // 拿到 state的list数组,利用map 方法,取出整合为新数组
        const newCartList = state.list.map(({ skuId, selected, count }) => {
          // 返回新数组的参数
          return { skuId, selected, count }
        })
        // 调用 合并购物车的api
        await mergeLocalCart(newCartList)
        // 2- 合并之后的效果-->  当前登录人就拥有了之前本地储存的购物车数据
      }
      // 3-获取当前登录人最新的购物车列表数据 -->  查接口
      dispatch('getLoginCartAction')
    },

    // 加入购物车的action方法
    /**
     *
     * @param {*} rootState 获取store的根=》通过根可以获取其它模块的数据
     * @param {*} good 当前加入购物车商品
     * async 异步函数=》语法糖=》返回Promise对象=》通过return 对外返回值（等价于reslove）
     */
    async addCartAction ({ commit, rootState, dispatch }, good) {
      // commit('updateValue', payload)
      if (rootState.user.profile.token) {
        // 已登录
        // console.log('登录加入购物车')
        // 1.存入数据库 调用线上加上购物车api,并传参good(商品),存入数据库
        await insertCart(good)
        // 2-获取当前登录人最新的购物车列表数据 -->  查接口
        dispatch('getLoginCartAction')
      } else {
        // 未登录
        commit('addCart', good)
        // return '未登录'
      }
    },

    // 删除购物车方法
    async delCartAction ({ commit, rootState, dispatch }, good) {
      if (rootState.user.profile.token) {
        // 已登录
        // console.log('登录加入购物车'
        await deleteCart([good.skuId])
        // 获取当前登录人最新的购物车列表数据 -->  查接口
        dispatch('getLoginCartAction')
      } else {
        // 未登录
        commit('delCart', good)
        // return '未登录'
      }
    },

    // 单选切换的方法
    async singleCheckAction ({ commit, rootState, dispatch }, good) {
      if (rootState.user.profile.token) {
        // 已登录
        // console.log('登录加入购物车')
        // ...good.good  是把全部的商品数据都展开传进来了
        // selected: good.isCheck  是把最新的是否选中的状态,再赋值一次,也传过来,它和good中的属性是一致的,但是后面的最新状态会覆盖之前老的
        await updateCart({ ...good.good, selected: good.isCheck })
        // 获取当前登录人最新的购物车列表数据 -->  查接口
        dispatch('getLoginCartAction')
      } else {
        // 未登录
        commit('singleCheck', good)
      }
    },

    // 全选切换的方法
    async selAllGoodsAction ({ commit, rootState, getters, dispatch }, selected) {
      if (rootState.user.profile.token) {
        // 已登录
        // console.log('登录加入购物车')
        // 拿到getters中的 validList(有效商品列表) 中的good的 skuId,重新组成一个数组
        const ids = getters.validList.map(good => good.skuId)
        // 调用全选切换的接口,并传输数据
        await checkAllCart({ selected, ids })
        // 获取当前登录人最新的购物车列表数据 -->  查接口
        dispatch('getLoginCartAction')
      } else {
        // 未登录
        commit('selAllGoods', selected)
        // return '未登录'
      }
    },

    // 修改数量的方法
    async changeCountAction ({ commit, rootState, dispatch }, good) {
      if (rootState.user.profile.token) {
        // 已登录
        // console.log('登录加入购物车')
        // ...good.good  是把全部的商品数据都展开传进来了
        // selected: good.isCheck  是把最新的是否选中的状态,再赋值一次,也传过来,它和good中的属性是一致的,但是后面的最新状态会覆盖之前老的
        await updateCart({ ...good.good, count: good.newCount })
        // 获取当前登录人最新的购物车列表数据 -->  查接口
        dispatch('getLoginCartAction')
      } else {
        // 未登录
        commit('changeCount', good)
        // return '未登录'
      }
    }
  }
}
